package EP.MetricasContenido;

import SBD.CRUD.SimilitudCosenoBD;
import Controladores.ControladorOperaciones;
import Controladores.ControladorScore;
import EP.Web.Pagina;
import EP.Web.RelacionPaginas;
import Jama.Matrix;
import SO.Operaciones.Operaciones;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

/**
* @class SimilitudCoseno
* @author Mauricio Alvarez.
* @brief Esta clase representa la clase SimilitudCoseno, correspondiente a una entidad principal (EP).
*/
public class SimilitudCoseno {

    /**
     *  @var private int id_pagina
     *  @brief identificador de la página en la BD.
    */
    private int id_pagina;
    /**
     *  @var private int id_relacion_pag
     *  @brief identificador de la página en la BD.
    */
    private int id_relacion_pag;
    /**
     *  @var private int id_pagina_objetivo
     *  @brief identificador del texto alrededor tomado como patrón.
    */
    private int id_pagina_objetivo;
    /**
     *  @var private String url_test
     *  @brief URL de la página a evaluar.
    */
    private String url_test;
    /**
     *  @var private String url_objetivo
     *  @brief URL de la página tomada como patrón.
    */
    private String url_objetivo;
    /**
     *  @var private String termino
     *  @brief Termino de la consulta.
    */
    private String termino;
    /**
     *  @var private double valor_sc
     *  @brief Valor de la similitud coseno.
    */
    private double valor_sc;
    /**
     *  @var private ControladorScore cscore
     *  @brief Variable global de tipo clase ControladorScore.
    */
    private ControladorScore cscore;
    /**
     *  @var private SimilitudCosenoBD scbd
     *  @brief Variable global de tipo clase SimilitudCosenoBD.
    */
    private SimilitudCosenoBD scbd;
    
    
    
    /**
     *  @var private ControladorOperaciones cop
     *  @brief Variable global de tipo clase ControladorOperaciones.
    */
    private ControladorOperaciones cop;


    //////////////////////////
    // CONSTRUCTOR
    //////////////////////////
    public SimilitudCoseno()
    {
        cscore = new ControladorScore();
        scbd = new SimilitudCosenoBD();
        cop = new ControladorOperaciones();
    }

    //////////////////////////
    // Getters & Setters
    //////////////////////////

    public int getId_pagina() {
        return id_pagina;
    }

    public void setId_pagina(int id_pagina) {
        this.id_pagina = id_pagina;
    }

    public String getTermino() {
        return termino;
    }

    public void setTermino(String termino) {
        this.termino = termino;
    }

    public String getUrl_objetivo() {
        return url_objetivo;
    }

    public void setUrl_objetivo(String url_objetivo) {
        this.url_objetivo = url_objetivo;
    }

    public double getValor_sc() {
        return valor_sc;
    }

    public void setValor_sc(double valor_sc) {
        this.valor_sc = valor_sc;
    }

    public int getId_relacion_pag() {
        return id_relacion_pag;
    }

    public void setId_relacion_pag(int id_relacion_pag) {
        this.id_relacion_pag = id_relacion_pag;
    }

    public String getUrl_test() {
        return url_test;
    }

    public void setUrl_test(String url_test) {
        this.url_test = url_test;
    }

    public int getId_pagina_objetivo() {
        return id_pagina_objetivo;
    }

    public void setId_pagina_objetivo(int id_pagina_objetivo) {
        this.id_pagina_objetivo = id_pagina_objetivo;
    }


    //////////////////////////
    // OPERACIONES
    //////////////////////////

    /**
     * @brief Realiza la operación matemática de la similitud coseno.
     * @param La matriz o vector patrón y la de prueba.
     * @return double
    */
    private double SimilaridadCoseno(Matrix targetMatrix, Matrix objetivoMatrix)
    {
        double ProductoPesos = targetMatrix.arrayTimes(objetivoMatrix).norm1();
        double ProductoNormas = targetMatrix.normF() * objetivoMatrix.normF();

        //Se valida que la distancia euclidiana no sea 0:
        if (ProductoNormas == 0)
        {
            return 0;
        }
        return ProductoPesos / ProductoNormas;
        
    }//FIN SimilaridadCoseno


    /**
     * @brief Invoca el cálculo la similitud coseno usando la norma.
     * @param El listado de tópicos, los resultados de las métricas de ranking
     * (score), el listado de páginas, el listado de relaciones de páginas, el
     * topico consultado, la opción seleccionada sobre que contenido hacer el
     * el cálculo, el umbral, el listado de stopwords y el largo del ranking.
     * @return void
    */
    public void CalcularSC(Map<String, Integer> Topico,
                           Map<Integer, List> ResultadosScore,
                           List<Pagina> ListaPaginas,
                           List<RelacionPaginas> ListaRelacionPaginas,
                           Map<String, Integer> Stopwords,
                           String TopicoConsultado,
                           int OpcionContenido,
                           double Umbral,
                           int Ranking,
                           int N_IDF_DINAMICO) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {


        ////////////////////////////////////////////////////////////////////////
        //PASO 0: Segun la selección de OpcionContenido (1:BODY/2:SURROUND TEXT)
        //        se calcula SC:
        ////////////////////////////////////////////////////////////////////////

        ////////////
        // BODY   //
        ////////////
        if (OpcionContenido == 1)
        {

            System.out.println("************************************************");
            System.out.println("**    CALCULO DE SIMILITUD COSENO  (BODY)     **");
            System.out.println("************************************************");

            //Id de la página:
            int id_pagina = 0;
            //Termino del Score:
            String termino;
            //Valor de los Scores:
            double TF_SN = 0;
            double TF_N = 0;
            double TF_S = 0;
            double TFIDF_SN = 0;
            double TFIDF_N = 0;
            double TFIDF_S = 0;
            double TFIDF_O_SN = 0;
            double TFIDF_O_N = 0;
            double TFIDF_O_S = 0;
            double OKAPI = 0;

            //Id_pagina target TF_SN (el de mayor score):
            int id_paginaTF_SN = 0;
            //Id_pagina target TF_N (el de mayor score):
            int id_paginaTF_N = 0;
            //Id_pagina target TF_S (el de mayor score):
            int id_paginaTF_S = 0;
            //Id_pagina target TFIDF_SN (el de mayor score):
            int id_paginaTFIDF_SN = 0;
            //Id_pagina target TFIDF_N (el de mayor score):
            int id_paginaTFIDF_N = 0;
            //Id_pagina target TFIDF_S (el de mayor score):
            int id_paginaTFIDF_S = 0;
            //Id_pagina target TFIDF_O_SN (el de mayor score):
            int id_paginaTFIDF_O_SN = 0;
            //Id_pagina target TFIDF_O_N (el de mayor score):
            int id_paginaTFIDF_O_N = 0;
            //Id_pagina target TFIDF_O_S (el de mayor score):
            int id_paginaTFIDF_O_S = 0;
            //Id_pagina target OKAPI (el de mayor score):
            int id_paginaOKAPI = 0;


            //Indica el numero de páginas a comparar en el  estudio:
            int Npaginas = ListaPaginas.size();
            //Indica el numero de terminos correspondientes al tópico o consulta:
            int Nterminos = Topico.size();


            //Matriz que guarda los valores TF_SN para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTF_SN = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores TF_N para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTF_N = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores TF_S para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTF_S = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores TFIDF_SN para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTFIDF_SN = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores TFIDF_N para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTFIDF_N = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores TFIDF_S para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTFIDF_S = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores TFIDF_O_SN para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTFIDF_O_SN = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores TFIDF_O_N para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTFIDF_O_N = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores TFIDF_O_S para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaTFIDF_O_S = new double[Nterminos][Npaginas];
            //Matriz que guarda los valores OKAPI para las páginas según termino (Termino x Pag)
            double[][] TerminoPaginaOKAPI = new double[Nterminos][Npaginas];


            //Indice i de terminos:
            int i = 0;
            //Indice j de páginas:
            int j = 0;


            ///////////////////////////////////////////////////////////////////////
            //PASO 1: Se obtiene los id_pagina de las páginas con mayor Score para
            //        la consulta (TARGET) (OK)
            ///////////////////////////////////////////////////////////////////////
            id_paginaTF_SN = cscore.ObtenerMejorPaginaTF_SN(Ranking);
            id_paginaTF_N = cscore.ObtenerMejorPaginaTF_N(Ranking);
            id_paginaTF_S = cscore.ObtenerMejorPaginaTF_S(Ranking);
            id_paginaTFIDF_SN = cscore.ObtenerMejorPaginaTFIDF_SN(Ranking);
            id_paginaTFIDF_N = cscore.ObtenerMejorPaginaTFIDF_N(Ranking);
            id_paginaTFIDF_S = cscore.ObtenerMejorPaginaTFIDF_S(Ranking);
            id_paginaTFIDF_O_SN = cscore.ObtenerMejorPaginaTFIDF_O_SN(Ranking);
            id_paginaTFIDF_O_N = cscore.ObtenerMejorPaginaTFIDF_O_N(Ranking);
            id_paginaTFIDF_O_S = cscore.ObtenerMejorPaginaTFIDF_O_S(Ranking);
            id_paginaOKAPI = cscore.ObtenerMejorPaginaOKAPI(Ranking);



                    System.out.println("++++++++++++  id_pagina max score    +++++++++++++++++++++++++");
                    System.out.println("id_paginaTF_S: "+ id_paginaTF_S);
                    System.out.println("id_paginaTFIDF_S: "+ id_paginaTFIDF_S);
                    System.out.println("id_paginaTFIDF_O_S: "+ id_paginaTFIDF_O_S);
                    System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");




            ////////////////////////////////////////////////////
            //PASO 2: Para cada página dentro de Score hacer:
            ////////////////////////////////////////////////////
            Set conjuntoScore = ResultadosScore.entrySet();
            Iterator it = conjuntoScore.iterator();

            while(it.hasNext())
            {
                //Se obtiene el par:
                Map.Entry me = (Map.Entry)it.next();
                //Se obtiene el id_pagina:
                id_pagina = (Integer) me.getKey();
                //Se obtienen los Scores para la página j:
                List<OkapiBM25> ListaScorePagina = new ArrayList();
                ListaScorePagina = (List<OkapiBM25>) me.getValue();

                //Para cada Score por Termino i hacer:
                for (int k=0; k <ListaScorePagina.size(); k++)
                {
                    //Se obtiene el termino del Score:
                    termino = ListaScorePagina.get(k).getTermino();
                    //Se obtiene el TF_SN para la página j:
                    TF_SN = ListaScorePagina.get(k).getTFij_SN();
                    //Se obtiene el TF_N para la página j:
                    TF_N = ListaScorePagina.get(k).getTFij_N();
                    //Se obtiene el TF_S para la página j:
                    TF_S = ListaScorePagina.get(k).getTFij_S();
                    //Se obtiene el TFIDF_SN para la página j:
                    TFIDF_SN = ListaScorePagina.get(k).getTfxIDF_SN();
                    //Se obtiene el TFIDF_N para la página j:
                    TFIDF_N = ListaScorePagina.get(k).getTfxIDF_N();
                    //Se obtiene el TFIDF_S para la página j:
                    TFIDF_S = ListaScorePagina.get(k).getTfxIDF_S();
                    //Se obtiene el TFIDF_O_SN para la página j:
                    TFIDF_O_SN = ListaScorePagina.get(k).getTfxIDF_O_SN();
                    //Se obtiene el TFIDF_O_N para la página j:
                    TFIDF_O_N = ListaScorePagina.get(k).getTfxIDF_O_N();
                    //Se obtiene el TFIDF_O_S para la página j:
                    TFIDF_O_S = ListaScorePagina.get(k).getTfxIDF_O_S();
                    //Se obtiene el OKAPI para la página j:
                    OKAPI = ListaScorePagina.get(k).getOkapi();


                    //Se almacena valor TF_SN para el termino i de la página j
                    TerminoPaginaTF_SN[i][(id_pagina-1)] = TF_SN;
                    //Se almacena valor TF_N para el termino i de la página j
                    TerminoPaginaTF_N[i][(id_pagina-1)] = TF_N;
                    //Se almacena valor TF_S para el termino i de la página j
                    TerminoPaginaTF_S[i][(id_pagina-1)] = TF_S;
                    //Se almacena valor TFIDF_SN para el termino i de la página j
                    TerminoPaginaTFIDF_SN[i][(id_pagina-1)] = TFIDF_SN;
                    //Se almacena valor TFIDF_N para el termino i de la página j
                    TerminoPaginaTFIDF_N[i][(id_pagina-1)] = TFIDF_N;
                    //Se almacena valor TFIDF_S para el termino i de la página j
                    TerminoPaginaTFIDF_S[i][(id_pagina-1)] = TFIDF_S;
                    //Se almacena valor TFIDF_O_SN para el termino i de la página j
                    TerminoPaginaTFIDF_O_SN[i][(id_pagina-1)] = TFIDF_O_SN;
                    //Se almacena valor TFIDF_O_N para el termino i de la página j
                    TerminoPaginaTFIDF_O_N[i][(id_pagina-1)] = TFIDF_O_N;
                    //Se almacena valor TFIDF_O_S para el termino i de la página j
                    TerminoPaginaTFIDF_O_S[i][(id_pagina-1)] = TFIDF_O_S;
                    //Se almacena valor OKAPI para el termino i de la página j
                    TerminoPaginaOKAPI[i][(id_pagina-1)] = OKAPI;


                    //BORRAR ESTO //////////////////////////////////////////////////////
                    System.out.println("+++++++++++++++++++++++++++++++++++++");
                    System.out.println("["+i+","+ (id_pagina-1) +"]"+".-id_pagina: "+ id_pagina);
                    System.out.println("["+i+","+ (id_pagina-1) +"]"+".-termino: "+ termino);
                    System.out.println("["+i+","+ (id_pagina-1) +"]"+".-TerminoPaginaTF_S: "+ TerminoPaginaTF_S[i][(id_pagina-1)]);
                    System.out.println("+++++++++++++++++++++++++++++++++++++");
                    //BORRAR ESTO //////////////////////////////////////////////////////


                    //Se aumenta el contador de la fila (i):
                    i++;


                }//FIN for (Terminos)

                //Se restablece el indice de las filas (Terminos):
                i = 0;
                //Se aumenta el indice de las columnas (Páginas):
                //j++;

            }//FIN while ResultadosScore (Paginas)


            ///////////////////////////////////////////////////////////////////////
            //PASO 3: Se calcula la similitud coseno entre la página TARGET (la de
            //        de mayor pje para el Score) y las páginas OBJETIVO (muestra)
            ///////////////////////////////////////////////////////////////////////

            //Matriz <Termino x Página> de Score
            Matrix termPag;

            //System.out.println("***************************************");
            //System.out.println("**     VARIANTE 1: SC TF_SN          **");
            //System.out.println("***************************************");

            //Matriz <Termino x Página> de Score para TF_SN:
            termPag = new Matrix(TerminoPaginaTF_SN);
            //Matriz Similitud Coseno TF_SN <Target x Páginas Objetivo> :
            Matrix SCTF_SN = new Matrix(1, Npaginas);
            //Matriz TARGET TF_SN:
            Matrix targetTF_SN = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTF_SN-1, id_paginaTF_SN-1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTF_SN = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno entre la matriz TARGET,OBJETIVO:
                SCTF_SN.set(0, np, SimilaridadCoseno(targetTF_SN, objetivoTF_SN));
            }




            //System.out.println("***************************************");
            //System.out.println("**     VARIANTE 2: SC TF_N          **");
            //System.out.println("***************************************");

            //Matriz <Termino x Página> de Score para TF_N:
            termPag = new Matrix(TerminoPaginaTF_N);
            //Matriz Similitud Coseno TF_N <Target x Páginas Objetivo> :
            Matrix SCTF_N = new Matrix(1, Npaginas);
            //Matriz TARGET TF_N:
            Matrix targetTF_N = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTF_N-1, id_paginaTF_N-1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTF_N = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno TF_N entre la matriz TARGET,OBJETIVO:
                SCTF_N.set(0, np, SimilaridadCoseno(targetTF_N, objetivoTF_N));
            }




            //System.out.println("***************************************");
            //System.out.println("**     VARIANTE 3: SC TF_S          **");
            //System.out.println("***************************************");


            //Matriz <Termino x Página> de Score para TF_S:
            termPag = new Matrix(TerminoPaginaTF_S);
            //Matriz Similitud Coseno TF_S <Target x Páginas Objetivo> :
            Matrix SCTF_S = new Matrix(1, Npaginas);
            //Matriz TARGET TF_S:
            Matrix targetTF_S = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTF_S - 1, id_paginaTF_S - 1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTF_S = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno TF_S entre la matriz TARGET,OBJETIVO:
                SCTF_S.set(0, np, SimilaridadCoseno(targetTF_S, objetivoTF_S));
            }




            //System.out.println("******************************************");
            //System.out.println("**     VARIANTE 4: SC TFIDF_SN          **");
            //System.out.println("******************************************");

            //Matriz <Termino x Página> de Score para TFIDF_SN:
            termPag = new Matrix(TerminoPaginaTFIDF_SN);
            //Matriz Similitud Coseno TFIDF_SN <Target x Páginas Objetivo> :
            Matrix SCTFIDF_SN = new Matrix(1, Npaginas);
            //Matriz TARGET TFIDF_SN:
            Matrix targetTFIDF_SN = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTFIDF_SN-1, id_paginaTFIDF_SN-1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTFIDF_SN = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno TF_N entre la matriz TARGET,OBJETIVO:
                SCTFIDF_SN.set(0, np, SimilaridadCoseno(targetTFIDF_SN, objetivoTFIDF_SN));
            }



            //System.out.println("******************************************");
            //System.out.println("**     VARIANTE 5: SC TFIDF_N           **");
            //System.out.println("******************************************");

            //Matriz <Termino x Página> de Score para TFIDF_N:
            termPag = new Matrix(TerminoPaginaTFIDF_N);
            //Matriz Similitud Coseno TFIDF_N <Target x Páginas Objetivo> :
            Matrix SCTFIDF_N = new Matrix(1, Npaginas);
            //Matriz TARGET TFIDF_N:
            Matrix targetTFIDF_N = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTFIDF_N - 1, id_paginaTFIDF_N - 1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTFIDF_N = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno TF_N entre la matriz TARGET,OBJETIVO:
                SCTFIDF_N.set(0, np, SimilaridadCoseno(targetTFIDF_N, objetivoTFIDF_N));
            }




            //System.out.println("******************************************");
            //System.out.println("**     VARIANTE 6: SC TFIDF_S           **");
            //System.out.println("******************************************");

            //Matriz <Termino x Página> de Score para TFIDF_S:
            termPag = new Matrix(TerminoPaginaTFIDF_S);
            //Matriz Similitud Coseno TFIDF_S <Target x Páginas Objetivo> :
            Matrix SCTFIDF_S = new Matrix(1, Npaginas);
            //Matriz TARGET TFIDF_S:
            Matrix targetTFIDF_S = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTFIDF_S - 1, id_paginaTFIDF_S - 1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTFIDF_S = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno TF_N entre la matriz TARGET,OBJETIVO:
                SCTFIDF_S.set(0, np, SimilaridadCoseno(targetTFIDF_S, objetivoTFIDF_S));
            }




            //System.out.println("******************************************");
            //System.out.println("**     VARIANTE 7: SC TFIDF_O_SN        **");
            //System.out.println("******************************************");

            //Matriz <Termino x Página> de Score para TFIDF_O_SN:
            termPag = new Matrix(TerminoPaginaTFIDF_O_SN);
            //Matriz Similitud Coseno TFIDF_O_SN <Target x Páginas Objetivo> :
            Matrix SCTFIDF_O_SN = new Matrix(1, Npaginas);
            //Matriz TARGET TFIDF_O_SN:
            Matrix targetTFIDF_O_SN = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTFIDF_O_SN - 1, id_paginaTFIDF_O_SN - 1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTFIDF_O_SN = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno TFIDF_O_SN entre la matriz TARGET,OBJETIVO:
                SCTFIDF_O_SN.set(0, np, SimilaridadCoseno(targetTFIDF_O_SN, objetivoTFIDF_O_SN));
            }



            //System.out.println("******************************************");
            //System.out.println("**     VARIANTE 8: SC TFIDF_O_N         **");
            //System.out.println("******************************************");

            //Matriz <Termino x Página> de Score para TFIDF_O_N:
            termPag = new Matrix(TerminoPaginaTFIDF_O_N);
            //Matriz Similitud Coseno TFIDF_O_SN <Target x Páginas Objetivo> :
            Matrix SCTFIDF_O_N = new Matrix(1, Npaginas);
            //Matriz TARGET TFIDF_O_SN:
            Matrix targetTFIDF_O_N = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTFIDF_O_N - 1, id_paginaTFIDF_O_N - 1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTFIDF_O_N = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno TFIDF_O_N entre la matriz TARGET,OBJETIVO:
                SCTFIDF_O_N.set(0, np, SimilaridadCoseno(targetTFIDF_O_N, objetivoTFIDF_O_N));
            }




            //System.out.println("******************************************");
            //System.out.println("**     VARIANTE 9: SC TFIDF_O_S         **");
            //System.out.println("******************************************");

            //Matriz <Termino x Página> de Score para TFIDF_O_S:
            termPag = new Matrix(TerminoPaginaTFIDF_O_S);
            //Matriz Similitud Coseno TFIDF_O_S <Target x Páginas Objetivo> :
            Matrix SCTFIDF_O_S = new Matrix(1, Npaginas);
            //Matriz TARGET TFIDF_O_S:
            Matrix targetTFIDF_O_S = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaTFIDF_O_S - 1, id_paginaTFIDF_O_S - 1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoTFIDF_O_S = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno TFIDF_O_S entre la matriz TARGET,OBJETIVO:
                SCTFIDF_O_S.set(0, np, SimilaridadCoseno(targetTFIDF_O_S, objetivoTFIDF_O_S));
            }



            //System.out.println("******************************************");
            //System.out.println("**     VARIANTE 10: SC OKAPI            **");
            //System.out.println("******************************************");

            //Matriz <Termino x Página> de Score para OKAPI:
            termPag = new Matrix(TerminoPaginaOKAPI);
            //Matriz Similitud Coseno OKAPI <Target x Páginas Objetivo> :
            Matrix SCOKAPI = new Matrix(1, Npaginas);
            //Matriz TARGET TFIDF_O_S:
            Matrix targetOKAPI = termPag.getMatrix( 0, termPag.getRowDimension() - 1, id_paginaOKAPI - 1, id_paginaOKAPI - 1);

            //Para el numero de páginas (np) hacer:
            for (int np = 0; np < Npaginas; np++)
            {
                //Matriz <Termino x Pagina> objetivo:
                Matrix objetivoOKAPI = termPag.getMatrix(0, termPag.getRowDimension() - 1, np, np);
                //Se calcula la similud coseno OKAPI entre la matriz TARGET,OBJETIVO:
                SCOKAPI.set(0, np, SimilaridadCoseno(targetOKAPI, objetivoOKAPI));
            }


            ////////////////////////////////////////////
            //PASO 3: Se guardan los calculos en la BD
            ////////////////////////////////////////////

            //POR BORRAR /////////////////////////////////////////////////////////////////
            System.out.println("--------------------------------------------------------");
            for (int np = 0; np < Npaginas; np++)
            {

                //Matriz SCMatrixTF_SN:
                System.out.println("[T:"+ id_paginaTF_SN +" VS O:"+ np +"] .-Matriz SCTF_SN ["+0+","+np+"] : "+ SCTF_SN.get(0, np));
                //Matriz SCTF_N:
                System.out.println("[T:"+ id_paginaTF_N +" VS O:"+ np +"] .-Matriz SCTF_N ["+0+","+np+"] : "+ SCTF_N.get(0, np));
                //Matriz SCTF_S:
                System.out.println("[T:"+ id_paginaTF_S +" VS O:"+ np +"] .-Matriz SCTF_S ["+0+","+np+"] : "+ SCTF_S.get(0, np));
                //Matriz SCTFIDF_SN:
                System.out.println("[T:"+ id_paginaTFIDF_SN +" VS O:"+ np +"] .-Matriz SCTFIDF_SN ["+0+","+np+"] : "+ SCTFIDF_SN.get(0, np));
                //Matriz SCTFIDF_N:
                System.out.println("[T:"+ id_paginaTFIDF_N +" VS O:"+ np +"] .-Matriz SCTFIDF_N ["+0+","+np+"] : "+ SCTFIDF_N.get(0, np));
                //Matriz SCTFIDF_S:
                System.out.println("[T:"+ id_paginaTFIDF_S +" VS O:"+ np +"] .-Matriz SCTFIDF_S ["+0+","+np+"] : "+ SCTFIDF_S.get(0, np));
                //Matriz SCTFIDF_SN:
                System.out.println("[T:"+ id_paginaTFIDF_O_SN +" VS O:"+ np +"] .-Matriz SCTFIDF_O_SN ["+0+","+np+"] : "+ SCTFIDF_O_SN.get(0, np));
                //Matriz SCTFIDF_N:
                System.out.println("[T:"+ id_paginaTFIDF_O_N +" VS O:"+ np +"] .-Matriz SCTFIDF_O_N ["+0+","+np+"] : "+ SCTFIDF_O_N.get(0, np));
                //Matriz SCTFIDF_S:
                System.out.println("[T:"+ id_paginaTFIDF_O_S +" VS O:"+ np +"] .-Matriz SCTFIDF_O_S ["+0+","+np+"] : "+ SCTFIDF_O_S.get(0, np));
                //Matriz OKAPI:
                System.out.println("[T:"+ id_paginaOKAPI +" VS O:"+ np +"] .-Matriz SCOKAPI ["+0+","+np+"] : "+ SCOKAPI.get(0, np));
                //POR BORRAR /////////////////////////////////////////////////////////////////

            }
            System.out.println("--------------------------------------------------------");
            //POR BORRAR /////////////////////////////////////////////////////////////////

            //Variable de clase:
            SimilitudCoseno sc;
            //url test:
            String url_test = null;
            //url objetivo:
            String url_objetivo = null;
            //ArrayList resultadosPaginaSC:
            List<SimilitudCoseno> resultadosPaginaSC = null;

            // (1) Map ResultadosSCTF_SN:
            Map<Integer, List> ResultadosSCTF_SN;
            // (2) Map ResultadosSCTF_N:
            Map<Integer, List> ResultadosSCTF_N;
            // (3) Map ResultadosSCTF_S:
            Map<Integer, List> ResultadosSCTF_S;
            // (4) Map ResultadosSCTFIDF_SN:
            Map<Integer, List> ResultadosSCTFIDF_SN;
            // (5) Map ResultadosSCTFIDF_N:
            Map<Integer, List> ResultadosSCTFIDF_N;
            // (6) Map ResultadosSCTFIDF_S:
            Map<Integer, List> ResultadosSCTFIDF_S;
            // (7) Map ResultadosSCTFIDF_O_SN:
            Map<Integer, List> ResultadosSCTFIDF_O_SN;
            // (8) Map ResultadosSCTFIDF_O_N:
            Map<Integer, List> ResultadosSCTFIDF_O_N;
            // (9) Map ResultadosSCTFIDF_O_S:
            Map<Integer, List> ResultadosSCTFIDF_O_S;
            // (10) Map ResultadosSCOKAPI:
            Map<Integer, List> ResultadosSCOKAPI;



            ////////////////////////////////////////////
            // (1) Para Similitud Coseno con SCTF_SN:
            ////////////////////////////////////////////
            ResultadosSCTF_SN = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTF_SN);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTF_SN)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina muestra:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_test(url_test);
                sc.setUrl_objetivo(url_objetivo);

                //Se setea el valor de la similitud coseno para SCTF_SN:
                sc.setValor_sc(SCTF_SN.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTF_SN:
                ResultadosSCTF_SN.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTF_SN



            ////////////////////////////////////////////
            // (2) Para Similitud Coseno con SCTF_N:
            ////////////////////////////////////////////
            ResultadosSCTF_N = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTF_N);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina test:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTF_N)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCTF_SN:
                sc.setValor_sc(SCTF_N.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTF_SN:
                ResultadosSCTF_N.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTF_N



            ////////////////////////////////////////////
            // (3) Para Similitud Coseno con SCTF_S:
            ////////////////////////////////////////////
            ResultadosSCTF_S = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTF_S);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTF_S)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCTF_SN:
                sc.setValor_sc(SCTF_S.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTF_SN:
                ResultadosSCTF_S.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTF_S



            ////////////////////////////////////////////
            // (4) Para Similitud Coseno con SCTFIDF_SN:
            ////////////////////////////////////////////
            ResultadosSCTFIDF_SN = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTFIDF_SN);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTFIDF_SN)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCTF_SN:
                sc.setValor_sc(SCTFIDF_SN.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTF_SN:
                ResultadosSCTFIDF_SN.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTFIDF_SN



            ////////////////////////////////////////////
            // (5) Para Similitud Coseno con SCTFIDF_N:
            ////////////////////////////////////////////
            ResultadosSCTFIDF_N = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTFIDF_N);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTFIDF_N)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCTFIDF_N:
                sc.setValor_sc(SCTFIDF_N.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTFIDF_N:
                ResultadosSCTFIDF_N.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTFIDF_N



            ////////////////////////////////////////////
            // (6) Para Similitud Coseno con SCTFIDF_S:
            ////////////////////////////////////////////
            ResultadosSCTFIDF_S = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTFIDF_S);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTFIDF_S)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCTFIDF_S:
                sc.setValor_sc(SCTFIDF_S.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTFIDF_S:
                ResultadosSCTFIDF_S.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTFIDF_S



            ////////////////////////////////////////////////
            // (7) Para Similitud Coseno con SCTFIDF_O_SN:
            ////////////////////////////////////////////////
            ResultadosSCTFIDF_O_SN = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTFIDF_O_SN);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTFIDF_O_SN)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCTFIDF_O_SN:
                sc.setValor_sc(SCTFIDF_O_SN.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTFIDF_O_SN:
                ResultadosSCTFIDF_O_SN.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTFIDF_O_SN



            ////////////////////////////////////////////////
            // (8) Para Similitud Coseno con SCTFIDF_O_N:
            ////////////////////////////////////////////////
            ResultadosSCTFIDF_O_N = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTFIDF_O_N);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTFIDF_O_N)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCTFIDF_O_N:
                sc.setValor_sc(SCTFIDF_O_N.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTFIDF_O_N:
                ResultadosSCTFIDF_O_N.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTFIDF_O_N



            ////////////////////////////////////////////////
            // (9) Para Similitud Coseno con SCTFIDF_O_S:
            ////////////////////////////////////////////////
            ResultadosSCTFIDF_O_S = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaTFIDF_O_S);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaTFIDF_O_S)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCTFIDF_O_S:
                sc.setValor_sc(SCTFIDF_O_S.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCTFIDF_O_S:
                ResultadosSCTFIDF_O_S.put(id_pagina, resultadosPaginaSC);

            }//FIN for SCTFIDF_O_S



            ////////////////////////////////////////////////
            // (10) Para Similitud Coseno con SCOKAPI:
            ////////////////////////////////////////////////
            ResultadosSCOKAPI = new HashMap();

            for (int np = 0; np < Npaginas; np++)
            {
                //Se instancia la estructua SC:
                sc = new SimilitudCoseno();
                //Se setean id_pagina objetivo:
                id_pagina = np+1;
                sc.setId_pagina(id_pagina);
                //Se setean id_pagina target:
                sc.setId_pagina_objetivo(id_paginaOKAPI);
                //Se setean el termino:
                sc.setTermino(TopicoConsultado);
                //Se setean la url de la página target y objetivo:
                for (int k=0; k<ListaPaginas.size(); k++)
                {
                    //Si el id_pagina se corresponde al del id_pagina target:
                    if (ListaPaginas.get(k).getId_pagina() == id_paginaOKAPI)
                    {
                        url_objetivo = ListaPaginas.get(k).getUrl();
                    }
                    //Si el id_pagina se corresponde al del id_pagina objetivo:
                    if (ListaPaginas.get(k).getId_pagina() == id_pagina)
                    {
                        url_test = ListaPaginas.get(k).getUrl();
                    }
                }
                sc.setUrl_objetivo(url_objetivo);
                sc.setUrl_test(url_test);

                //Se setea el valor de la similitud coseno para SCOKAPI:
                sc.setValor_sc(SCOKAPI.get(0, np));

                //Se guarda en el List el resultado para esta página objetivo:
                resultadosPaginaSC = new ArrayList();
                resultadosPaginaSC.add(sc);

                //Se guardan los resultados de las paginas para SCOKAPI:
                ResultadosSCOKAPI.put(id_pagina, (ArrayList) resultadosPaginaSC);

            }//FIN for SCOKAPI


            //////////////////////////////////////////
            //PASO 4: Se guardan los datos en la BD:
            //////////////////////////////////////////
            scbd.GuardarSimilitudCoseno(ResultadosSCTF_SN, ResultadosSCTF_N, ResultadosSCTF_S,
                                        ResultadosSCTFIDF_SN, ResultadosSCTFIDF_N, ResultadosSCTFIDF_S,
                                        ResultadosSCTFIDF_O_SN, ResultadosSCTFIDF_O_N, ResultadosSCTFIDF_O_S,
                                        ResultadosSCOKAPI, TopicoConsultado, Umbral, Ranking);


            //////////////////////////////////////////////////
            //PASO 5: Se calcula el ranking de las páginas
            //////////////////////////////////////////////////
            scbd.RankearMedicionSC(Ranking, TopicoConsultado);

            
        }//FIN IF BODY


        ////////////////////////////////////////////////////////////////////////
        // PREDICTOR      //////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////

        if (OpcionContenido == 2)
        {
            System.out.println("*****************************************************");
            System.out.println("**    CALCULO DE SIMILITUD COSENO  (PREDICTOR)     **");
            System.out.println("*****************************************************");

            ///////////////////////////////////////////////////////////////////
            // MODIFICACIÓN (Lunes 03 de Octubre)
            // - Uso del predictor.
            // - Calculo de vectores: Consulta Q vs Contenido páginas.
            ///////////////////////////////////////////////////////////////////

            int id_relacion_pagina;
            double pje_SCTF_IDF_N_AT;
            double pje_SCTF_IDF_N_TA;
            double pje_SCTF_IDF_N_H;
            double pje_SCTF_IDF_N_T;
            double pje_SCTF_IDF_N_TOTAL;
            double pje_SCTF_IDF_S_AT;
            double pje_SCTF_IDF_S_TA;
            double pje_SCTF_IDF_S_H;
            double pje_SCTF_IDF_S_T;           
            double pje_SCTF_IDF_S_TOTAL;
            
            int tamMuestra = N_IDF_DINAMICO;
            
            Map<String,Integer> NiD = new HashMap(); //HashMap que guarda el conteo globarl de terminos en la muestra.
            
            
            //Se "simula" el recorrido del crawler calculando el contenido del
            //HashMap "ListaRelacionPaginas":
            
            for (int i=0; i<ListaRelacionPaginas.size(); i++)
            {
                //Se extrae la información necesaria para el procesamiento:
                id_relacion_pagina = ListaRelacionPaginas.get(i).getId_relacion_pagina();
                
                //Se calcular el IDF de los terminos en la muestra:
                String documento =  ListaRelacionPaginas.get(i).getTitle() + " " +
                                    ListaRelacionPaginas.get(i).getHeader() + " " +
                                    ListaRelacionPaginas.get(i).getTexto_alrededor() + " " +
                                    ListaRelacionPaginas.get(i).getAnchor_text();
                
                //Se calcula el Ni dinamico:
                IDF idf = new IDF();
                NiD = idf.CalcularNi(Topico, documento, NiD);
                
                /*
                System.out.println(i++ +". BORRAR ESTO .--------------------------");
                Set set = NiD.entrySet();

                Iterator it = set.iterator();

                while(it.hasNext()){
                      Map.Entry me = (Map.Entry)it.next();
                      System.out.println(me.getKey() + " : " + me.getValue() );
                }   
                System.out.println("BORRAR ESTO .--------------------------");
                 * */

                //Calculo de pjes para SCTF-IDF-N:
                pje_SCTF_IDF_N_AT = similitudCosenoTFIDFNorm(Topico, ListaRelacionPaginas.get(i).getAnchor_text(), NiD, tamMuestra);
                pje_SCTF_IDF_N_TA = similitudCosenoTFIDFNorm(Topico, ListaRelacionPaginas.get(i).getTexto_alrededor(), NiD, tamMuestra);
                pje_SCTF_IDF_N_H = similitudCosenoTFIDFNorm(Topico, ListaRelacionPaginas.get(i).getHeader(), NiD, tamMuestra);
                pje_SCTF_IDF_N_T = similitudCosenoTFIDFNorm(Topico, ListaRelacionPaginas.get(i).getTitle(), NiD, tamMuestra);
                //Se calculan los pjes. globales:
                //AT = 0.4
                //TA = 0.2
                //H = 0.3
                //T = 0.1
                pje_SCTF_IDF_N_TOTAL = 0.4 * pje_SCTF_IDF_N_AT + 0.2 * pje_SCTF_IDF_N_TA + 0.3 * pje_SCTF_IDF_N_H + 0.1 * pje_SCTF_IDF_N_T;
                
                //Calculo de pjes. para SCTF-IDF-S:
                pje_SCTF_IDF_S_AT = similitudCosenoTFIDFSuavisada(Topico, ListaRelacionPaginas.get(i).getAnchor_text(), NiD, tamMuestra);
                pje_SCTF_IDF_S_TA = similitudCosenoTFIDFSuavisada(Topico, ListaRelacionPaginas.get(i).getTexto_alrededor(), NiD, tamMuestra);
                pje_SCTF_IDF_S_H = similitudCosenoTFIDFSuavisada(Topico, ListaRelacionPaginas.get(i).getHeader(), NiD, tamMuestra);
                pje_SCTF_IDF_S_T = similitudCosenoTFIDFSuavisada(Topico, ListaRelacionPaginas.get(i).getTitle(), NiD, tamMuestra);
                //Se calculan los pjes. globales:
                //AT = 0.4
                //TA = 0.2
                //H = 0.3
                //T = 0.1
                pje_SCTF_IDF_S_TOTAL = 0.4 * pje_SCTF_IDF_S_AT + 0.2 * pje_SCTF_IDF_S_TA + 0.3 * pje_SCTF_IDF_S_H + 0.1 * pje_SCTF_IDF_S_T;
                           
                
                System.out.println(".............. BORRAR ESTO - PREDICTOR SCoseno.....................");
                System.out.println("id_relación_pagina: "+ id_relacion_pagina);
                System.out.println("pje_SCTF_IDF_N_TOTAL: "+ pje_SCTF_IDF_N_TOTAL + " = " + pje_SCTF_IDF_N_AT + "(AT) + " + pje_SCTF_IDF_N_TA + "(TA) + " + pje_SCTF_IDF_N_H + "(H) + " + pje_SCTF_IDF_N_T +" (T)");
                System.out.println("pje_SCTF_IDF_S_TOTAL: "+ pje_SCTF_IDF_S_TOTAL + " = " + pje_SCTF_IDF_S_AT + "(AT) + " + pje_SCTF_IDF_S_TA + "(TA) + " + pje_SCTF_IDF_S_H + "(H) + " + pje_SCTF_IDF_S_T +" (T)");
                System.out.println(".............. BORRAR ESTO - PREDICTOR .....................");
                
                //Se ingresan los datos a la BD:
                scbd.GuardarSimilitudCoseno_P(id_relacion_pagina, pje_SCTF_IDF_N_TOTAL, pje_SCTF_IDF_S_TOTAL);
                
            }

        }//FIN IF PREDICTOR

    }//FIN CalcularSC
    
    
    
   /**
     * Calculo de distancia coseno por medio del modelo TF normalizado
     * @param terminosTopico
     * @param documento
     * @return 
     */
    public double similitudCosenoTFIDFNorm(Map terminosTopico, String documento, Map<String,Integer> NiD, int tamMuestra) 
    {
        Map<String, Integer> terminosDoc = null;   // Terminos de la ontologia de forma < Termino, Frecuencia)
        List<String> vocabulario = null;         // Union de los terminos del documento y ontologia, que permite generar los vectores
        double[][] vectorTerminosTopico;                    // Vector unitario de los terminos de la ontologia 
        double[][] vectorTerminosDoc;                       // Vector de los terminos del documento
        double puntajeCoseno = 0;
        Iterator it;
        double ni = 1;  //Cantidad de páginas que contienen el termino i dentro de la muestra.

        // Los terminos del documento vienen tokenizados en la lista
        // El documento no viene procesado( ni tokenizado ni se le efectuo stemming) solo se le sacaron los stopwords
         try{
        
        if(documento==null)
            return puntajeCoseno;
        else
        if (documento.equals("") || documento.isEmpty()) {
            return 0;
        }
        
        int maxFrecuenciaDoc = 1;      // Maxima frecuencia del vector documento 
        int maxFrecuenciaTopic = 1;    // Maxima frecuencia del vector de terminos del topico

        terminosDoc = new HashMap();   // Terminos de la ontologia de forma < Termino, Frecuencia)
        vocabulario = new ArrayList(); // Union de los terminos del documento y ontologia, que permite generar los vectores
        
        // Se procesa el documento de manera de extraer los terminos del documento 
        StringTokenizer tokens = new StringTokenizer(documento);
        while (tokens.hasMoreTokens()) {
            //String token = tokens.nextToken();
            String token = tokens.nextToken();
            if (!terminosDoc.containsKey(token)) {
                terminosDoc.put(token, 1);
            } else {
                terminosDoc.put(token, Integer.parseInt(terminosDoc.get(token).toString()) + 1);
            }       
        }


        /** Se genera el vocabulario: terminosDoc UNION terminosTopico*/
        /// Se aprovecha de extraer el elemento de mayor frecuencia
        it = terminosDoc.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();

            /// Se verifica la frecuencia del termino para extrae finalmente el termino de mayor frecuencia
            int frecuencia = Integer.parseInt(e.getValue().toString());
            if (maxFrecuenciaDoc < frecuencia) {
                maxFrecuenciaDoc = frecuencia;
            }

            if (!vocabulario.contains(e.getKey().toString())) {
                vocabulario.add(e.getKey().toString());      
            }
        }

        it = terminosTopico.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry t = (Map.Entry) it.next();

            /// Se verifica la frecuencia del termino para extrae finalmente el elmetno de mayor frecuencia
            int frecuencia = Integer.parseInt(t.getValue().toString());
            if (maxFrecuenciaTopic < frecuencia) {
                maxFrecuenciaTopic = frecuencia;
            }

            String term = t.getKey().toString();

            if (!vocabulario.contains(term)) {
                vocabulario.add(term);
            }
        }

        // Se instancian los vectores
        int tamañoVocabulario = vocabulario.size();
        vectorTerminosTopico = new double[tamañoVocabulario][1];
        vectorTerminosDoc = new double[tamañoVocabulario][1];

        // Se genera el vector binario del documento
        int i = 0;
        it = terminosDoc.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            String termino = e.getKey().toString();
            Double tf = Double.parseDouble(e.getValue().toString());

            /// Solo si la maxima frecuencia supera el valor 1 se efectua la normalizacion
            if (maxFrecuenciaDoc > 1);
            tf = tf / maxFrecuenciaDoc;

            //Se calcula el TF-IDF Normalizado:
            if (NiD.containsKey(termino)==true)
            {
                //Se valida si el ni = 0:
                if(NiD.get(termino) == 0){
                    ni = 1;
                }else{
                    ni = NiD.get(termino);
                }
                
                System.out.println(termino + ".- Cantidad ni"+ ni);                
                vectorTerminosDoc[i][0] = tf * Math.log10(Double.valueOf(tamMuestra/ni));
                
            }else{
                
                System.out.println(termino + ".- Cantidad ni"+ ni);  
                vectorTerminosDoc[i][0] = tf * Math.log10(Double.valueOf(tamMuestra/1));
            }

            i++;
        }

        // Se genera el vector binario de los terminos del topico
        i = 0;
        it = vocabulario.iterator();
        while (it.hasNext()) {
            String e = (String) it.next();
            if (terminosTopico.containsKey(e)) {

                Double valor = Double.parseDouble(terminosTopico.get(e).toString());
                /// Solo si la maxima frecuencia supera el valor 1 se efectua la normalizacion
                if (maxFrecuenciaTopic > 1);
                valor = valor / maxFrecuenciaTopic;
                
                vectorTerminosTopico[i][0] = valor;
            }
            i++;
        }

        Matrix doc = new Matrix(vectorTerminosDoc);
        Matrix topico = new Matrix(vectorTerminosTopico);

        double productoPunto = doc.arrayTimes(topico).norm1();     // ArrayTimes : Multiplicacion,  Norm1: Suma de los elementos
        double distanciaEuclidiana = doc.normF() * topico.normF(); //  NormF:Raiz cuadrada de la suma de los cuadrados de los elementos
        
        //Si la distancia euclidiana es cero, se deja en 1:
        if (distanciaEuclidiana == 0)
        {
            distanciaEuclidiana = 1;
        }
        
        puntajeCoseno = productoPunto / distanciaEuclidiana;
        
        //System.out.println("productoPunto: "+ productoPunto);
        //System.out.println("distanciaEuclidiana: "+ distanciaEuclidiana);
        //System.out.println("puntajeCoseno: "+ puntajeCoseno);

        }
        catch(Exception e){
        
        }
     // En casos que el documento pese mucho, puede ocupar mucho espacio y Sobrepasar el Java Heap
        catch (OutOfMemoryError o) {
            System.err.println("Out of Memory, Java Heap Space Similitud coseno:");

        }
        return puntajeCoseno; 

    }//FIN similitudCosenoTFNorm
    
    
   /**
     * Calculo de distancia coseno por medio del modelo TF normalizado
     * @param terminosTopico
     * @param documento
     * @return 
     */
    public double similitudCosenoTFIDFSuavisada(Map terminosTopico, String documento, Map<String,Integer> NiD, int tamMuestra) 
    {
        Map<String, Integer> terminosDoc = null;   // Terminos de la ontologia de forma < Termino, Frecuencia)
        List<String> vocabulario = null;         // Union de los terminos del documento y ontologia, que permite generar los vectores
        double[][] vectorTerminosTopico;                    // Vector unitario de los terminos de la ontologia 
        double[][] vectorTerminosDoc;                       // Vector de los terminos del documento
        double puntajeCoseno = 0;
        Iterator it;
        double ni=1;

        // Los terminos del documento vienen tokenizados en la lista
        // El documento no viene procesado( ni tokenizado ni se le efectuo stemming) solo se le sacaron los stopwords
         try{
        
        if(documento==null)
            return puntajeCoseno;
        else
        if (documento.equals("") || documento.isEmpty()) {
            return 0;
        }
        
        int maxFrecuenciaDoc = 1;     // Maxima frecuencia del vector documento 
        int maxFrecuenciaTopic = 1;   // Maxima frecuencia del vector de terminos del topico

        terminosDoc = new HashMap();   // Terminos de la ontologia de forma < Termino, Frecuencia)
        vocabulario = new ArrayList();         // Union de los terminos del documento y ontologia, que permite generar los vectores
        
        // Se procesa el documento de manera de extraer los terminos del documento 
        StringTokenizer tokens = new StringTokenizer(documento);
        while (tokens.hasMoreTokens()) {
            //String token = tokens.nextToken();
            String token = tokens.nextToken();
            if (!terminosDoc.containsKey(token)) {
                terminosDoc.put(token, 1);
            } else {
                terminosDoc.put(token, Integer.parseInt(terminosDoc.get(token).toString()) + 1);
            }       
        }


        /** Se genera el vocabulario: terminosDoc UNION terminosTopico*/
        /// Se aprovecha de extraer el elemtno de mayor frecuencia
        it = terminosDoc.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();

            /// Se verifica la frecuencia del termino para extrae finalmente el elmetno de mayor frecuencia
            int frecuencia = Integer.parseInt(e.getValue().toString());
            if (maxFrecuenciaDoc < frecuencia) {
                maxFrecuenciaDoc = frecuencia;
            }

            if (!vocabulario.contains(e.getKey().toString())) {
                vocabulario.add(e.getKey().toString());      
            }
        }

        it = terminosTopico.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry t = (Map.Entry) it.next();

            /// Se verifica la frecuencia del termino para extrae finalmente el elmetno de mayor frecuencia
            int frecuencia = Integer.parseInt(t.getValue().toString());
            if (maxFrecuenciaTopic < frecuencia) {
                maxFrecuenciaTopic = frecuencia;
            }

            String term = t.getKey().toString();
            if (!vocabulario.contains(term)) {
                vocabulario.add(term);

            }
        }

        // Se instancian los vectores
        int tamañoVocabulario = vocabulario.size();
        vectorTerminosTopico = new double[tamañoVocabulario][1];
        vectorTerminosDoc = new double[tamañoVocabulario][1];

        // Se genera el vector binario del documento
        int i = 0;
        it = terminosDoc.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            String termino = e.getKey().toString();
            Double tf = Double.parseDouble(e.getValue().toString());

            /// Solo si la maxima frecuencia supera el valor 1 se efectua la normalizacion
            if (maxFrecuenciaDoc > 1);
                tf = tf / maxFrecuenciaDoc;

            //Se calcula el TF-IDF suavizado:
            //Se calcula el TF-IDF Normalizado:
            if (NiD.containsKey(termino)==true)
            {
                //Se valida si el ni = 0:
                if(NiD.get(termino) == 0){
                    ni = 1;
                }else{
                    ni = NiD.get(termino);
                }
                
                System.out.println(termino + ".- Cantidad ni"+ ni);  
                vectorTerminosDoc[i][0] = (1 + Math.log10(tf)) * Math.log10(Double.valueOf(tamMuestra/ni));
                
            }else{
                
                System.out.println(termino + ".- Cantidad ni"+ ni);  
                vectorTerminosDoc[i][0] = (1 + Math.log10(tf)) * Math.log10(Double.valueOf(tamMuestra/1));
            }
            
            i++;
        }

        // Se genera el vector binario de los terminos del topico
        i = 0;
        it = vocabulario.iterator();
        while (it.hasNext()) {
            String e = (String) it.next();
            if (terminosTopico.containsKey(e)) {

                Double valor = Double.parseDouble(terminosTopico.get(e).toString());
                /// Solo si la maxima frecuencia supera el valor 1 se efectua la normalizacion
                if (maxFrecuenciaTopic > 1);
                valor = valor / maxFrecuenciaTopic;
                vectorTerminosTopico[i][0] = 1 + Math.log10(valor);
            }
            i++;
        }

        Matrix doc = new Matrix(vectorTerminosDoc);
        Matrix topico = new Matrix(vectorTerminosTopico);

        double productoPunto = doc.arrayTimes(topico).norm1();     // ArrayTimes : Multiplicacion,  Norm1: Suma de los elementos
        double distanciaEuclidiana = doc.normF() * topico.normF(); //  NormF:Raiz cuadrada de la suma de los cuadrados de los elementos

        //Si la distancia euclidiana es cero, se deja en 1:
        if (distanciaEuclidiana == 0)
        {
            distanciaEuclidiana = 1;
        }        
        
        puntajeCoseno = productoPunto / distanciaEuclidiana;

        }
        catch(Exception e){
        
        }
     // En casos que el documento pese mucho, puede ocupar mucho espacio y Sobrepasar el Java Heap
        catch (OutOfMemoryError o) {
            System.err.println("Out of Memory, Java Heap Space Similitud coseno:");

        }
        return puntajeCoseno; 

    }//FIN similitudCosenoTFNorm   


}//FIN CLASE SimilitudCoseno  //////////////////////////////////////////////////